package Java8;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Author suoyue_zhan
 * @Date 2021/3/12 11:16
 * @Description StreamList的使用
 */
public class StreamListTest {

    public static void main(String[] args) {
        streamListUse(initialization());
        System.out.println("================*****================");
        streamDistinct(initialization());
    }


    //List<XXXX>的stream去重
    private static void streamDistinct(List<Student> studentList) {
        //对于单一的列表可以直接使用distinct()去重 - distinct 方法无参数可操作
        List<String> list = Arrays.asList("赵","钱","孙","李","周","吴","郑","王","周","李");
        System.out.println(list);
        String strList = list.stream().distinct().collect(Collectors.joining(","));
        System.out.println(strList);

        //对象列表的字段去重
        List<Student> students = studentList.stream().filter(distinctByKey(Student::getName)).collect(Collectors.toList());
        for (Student student : students) {
            System.out.print(student.getName()+" ");
        }

    }

    /**
     * stream的去重
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    //List<XXXX>的stream使用
    private static void streamListUse(List<Student> studentList){

        //根据List列表里Student对象的id字段划分：key为id，value为Student对象的列表
        Map<String,List<Student>> mapRe = studentList.stream().collect(Collectors.groupingBy(Student::getId));
        for(Map.Entry<String, List<Student>> entry : mapRe.entrySet()){
            List<Student> list = entry.getValue();
            //遍历所有name值
            list.forEach(it -> {
                String name = it.getName();
                //执行其他操作
                System.out.print(name+" ");
            });
            //统计名字为suoyue-5的人数
            long countName = list.stream().filter(it -> "suoyeu-5".equals(it.getName())).collect(Collectors.counting());
            //统计分数
            Double scoreSum = list.stream().collect(Collectors.summingDouble(Student::getScore));
            System.out.println("\ncountName: "+countName+"\tscoreSum: "+scoreSum);
        }
    }

    //初始化数据
    private static List<Student> initialization(){
        List<Student> studentList = new ArrayList<>();
        //初始化数据
        for(int i=0;i<6;i++){
            Student student = new Student("20170390001","suoyeu-"+i,80.0+i);
            studentList.add(student);
        }
        Student student = new Student("20170390001","suoyeu-"+5,80.0);
        studentList.add(student);
        for(int i=0;i<10;i++){
            Student st5 = new Student("20170390002","suoyeu-"+i,75.0+i);
            studentList.add(st5);
        }
        return studentList;
    }

    //Student实体类
    private static class Student {
        //ID
        String id;
        //名字
        String name;
        //分数
        double score;
        //get/set方法
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public double getScore() {
            return score;
        }
        public void setScore(double score) {
            this.score = score;
        }
        public Student(String id, String name, double score) {
            this.name = name;
            this.id = id;
            this.score = score;
        }
    }

}
